package gui.document;

import gui.EntryPresentation;
import gui.GuiUtils;
import gui.Presentation;
import gui.RowPresentation;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Iterator;

import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.NumberFormatter;

import logic.Document;
import logic.DocumentDescription;
import logic.DocumentEntry;
import logic.Entry;
import logic.Row;
import logic.Template;
import logic.TemplateEntry;
import logic.Type;

import com.pallas.swing.date.DateComboBox;

public class DocumentPresentation extends Presentation {
	private static final class DocumentRowPresentation extends RowPresentation {
		public DocumentRowPresentation() {
			ep = new EntryPresentation() {

				public JComponent visulize(final Entry entry) {
					JPanel drawPanel = new JPanel();
					JComponent component = null;
					JLabel label = new javax.swing.JLabel();
					switch (((DocumentEntry) entry).getTemplateEntry().getType().ordinal()) {
						case Type.DATE:
							final DateComboBox dateComboBox = new DateComboBox();
							Date value = (Date) entry.getValue();
							dateComboBox.setDate(value == null ? new Date() : value);
							dateComboBox.addItemListener(new ItemListener() {

								public void itemStateChanged(ItemEvent e) {
									entry.setValue(dateComboBox.getDate());
								}

							});
							component = dateComboBox;
							break;
						case Type.DECIMAL: {
							NumberFormatter nf = new NumberFormatter(new DecimalFormat("#0.0#;(#0.0#)"));
							final JFormattedTextField textField1 = new JFormattedTextField(nf);
							textField1.setValue(entry.getValue() == null ? new BigDecimal(0) : entry.getValue());
							// textField1.setText(String.valueOf(entry.getValue()));
							component = textField1;
							textField1.getDocument().addDocumentListener(new DocumentListener() {
								@Override
								public void changedUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());
								}

								@Override
								public void insertUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());

								}

								@Override
								public void removeUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());

								}
							});
						}
							break;
						case Type.INTEGER: {
							NumberFormatter nf = new NumberFormatter(new DecimalFormat("#0;(#0)"));
							final JFormattedTextField textField1 = new JFormattedTextField(nf);
							textField1.setValue(entry.getValue() == null ? new Integer(0) : entry.getValue());
							component = textField1;
							textField1.getDocument().addDocumentListener(new DocumentListener() {
								@Override
								public void changedUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());
								}

								@Override
								public void insertUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());

								}

								@Override
								public void removeUpdate(DocumentEvent ee) {
									entry.setValue(textField1.getValue());

								}
							});
						}
							break;
						case Type.STRING:
							final JTextField textField = new javax.swing.JTextField();
							textField.setText(entry.getValue() == null ? "" : entry.getValue().toString());
							component = textField;
							textField.getDocument().addDocumentListener(new DocumentListener() {
								@Override
								public void changedUpdate(DocumentEvent ee) {
									entry.setValue(textField.getText());
								}

								@Override
								public void insertUpdate(DocumentEvent ee) {
									entry.setValue(textField.getText());

								}

								@Override
								public void removeUpdate(DocumentEvent ee) {
									entry.setValue(textField.getText());

								}
							});
							break;

					}

					label.setText(entry.getLabel());

					drawPanel.setLayout(new BoxLayout(drawPanel, BoxLayout.Y_AXIS));
					GuiUtils.borderPanel(drawPanel).add(label, BorderLayout.WEST);
					// drawPanel.add(label);
					drawPanel.add(component);

					
					return drawPanel;
				}

			};

		}

		@Override
		public void postVisulize(Row row, JPanel panel) {

		}

		@Override
		public void preVisulize(Row row, JPanel panel) {

		}
	}

	public DocumentPresentation() {
		super(new DocumentRowPresentation());
	}

	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		DocumentPresentation presentation = new DocumentPresentation();
		Object o = null;
		Object o2 = null;
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./res/templ"));
			o = ois.readObject();
			ObjectInputStream ois2 = new ObjectInputStream(new FileInputStream("./res/doc"));
			o2 = ois2.readObject();
		} catch (Exception e2) {

			e2.printStackTrace();
		}
		final Template template = o instanceof Template ? (Template) o : new Template();
		final Document document;
		boolean created = true;
		if (o2 instanceof Document) {
			created = false;
			document = (Document) o2;
			((Document) o2).setTemplate(template);
			document.setDescription(new DocumentDescription("1", new Date(), null));
		} else {

			document = new Document(template, new DocumentDescription("1", new Date(), null));
		}
		if (created)
		for (Row row : template) {
			for (Iterator<? extends Entry> iterator = row.iterator(); iterator.hasNext();) {
				TemplateEntry next = (TemplateEntry) iterator.next();
					switch (next.getType().ordinal()) {
						case Type.DATE:
						document.setValue(next, new Date());
						break;
						case Type.DECIMAL:
						document.setValue(next, new BigDecimal(1));
						break;
						case Type.INTEGER:
						document.setValue(next, new Integer(1));
						break;
						case Type.STRING:
						document.setValue(next, "");
						break;
				}

			}

		}
		JFrame frame = new JFrame();
		frame.setTitle("Document test");

		frame.setLayout(new BorderLayout());
		frame.add(presentation.vizulize(document), BorderLayout.NORTH);
		frame.pack();
		frame.doLayout();
		frame.setSize(new Dimension(500, 500));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				try {
					ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("./res/doc"));
					oos.writeObject(document);
					oos.close();
				} catch (Exception e1) {

					e1.printStackTrace();
				}
			}
		});
	}
}
